﻿// Copyright (c) egmkang wang. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

namespace XServer.SDK
{
    using System;
    using System.Collections.Concurrent;

    public class ProfileInfo
    {
        public ProfileInfo(ushort msgid)
        {
            this.msgid = msgid;
            this.count = new AtomicInt64(0);
            this.min = new AtomicInt64(long.MaxValue);
            this.max = new AtomicInt64(0);
            this.mean = new AtomicInt64(0);
        }
        readonly ushort msgid;

        public readonly AtomicInt64 count;
        public readonly AtomicInt64 min;
        public readonly AtomicInt64 max;
        public readonly AtomicInt64 mean;
    }

    public sealed class Profile
    {
        //是否开启profile
        public static bool Enbale { get; set; }

        public static ProfileInfo GetInfo(ushort msgid)
        {
            ProfileInfo info = null;
            if (!map.TryGetValue(msgid, out info))
            {
                info = new ProfileInfo(msgid);
                map.TryAdd(msgid, info);
            }
            return info;
        }

        public static void Update(ushort msgid, long num)
        {
            ProfileInfo info = GetInfo(msgid);
            if (num < info.min)
            {
                info.min.Store(num);
            }
            if (num > info.max)
            {
                info.max.Store(num);
            }
            long mean = (info.mean.Load() * info.count.Load() + num) / (info.count.Load() + 1);
            info.count.Add(1);
            info.mean.Store(mean);
        }

        static ConcurrentDictionary<ushort, ProfileInfo> map = new ConcurrentDictionary<ushort, ProfileInfo>();
    }
}
